Shell基础知识

GO

这些内容是在学习Shell脚本之前必须要掌握的Shell基础知识。

Shell 初相识

什么是Shell

Shell 是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。在Shell和计算机硬件中间还有一层东西,那就是系统内核。用户在使用计算机的时候,直接面对的并不是计算机硬件,而是Shell,用户把指令告诉Shell,然后Shell再传输给系统内核,接着内核再去支配计算机硬件去执行各种操作。

Shell的版本有很多,但是初学时所接触的Linux发布版本(RedHat或CentOS系列)默认安装的Shell版本是bash(即Bourne Again Shell),它是sh(Bourne Shell)的增强版本。Bourne Shell是最早流行起来的一个Shell版本。其创始人是Steven Bourne,为了纪念他而将其命名为Bourne Shell,简称sh。

Shell的特性

命令记录历史

history

history:用来查看命令历史列表。

  • 我们执行过的命令bash都会记录,预设可以记录1000条历史命令,这些命令保存在用户的家目录下的 .bash_history 文件中。
  • 需要注意的是,只有当用户正常退出当前Shell时,在当前Shell中运行过的命令才会保存至该文件里。
  • 我们可以自定义命令历史的大小,可以更改在配置文件/etc/profile 中的 HISTSIZE 环境变量。比如我们可以将其更改为2000。
  • 我们也可以设置一下命令历史的记录格式,比如在每条命令前加上其被执行的时间,这时我们应该设置 HISTTIMEFORMAT 环境变量,也是在配置文件 /etc/profile 中进行设置,为了方便查看,可以在 HISTSIZE 下面增加一条:HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S"
  • 我们可以把记录命令历史的文件设置成永久保存的权限,即不允许删除其内容,只能追加:chattr +a ~/.bash_history
  • Ctrl+r:可以搜索命令历史来执行

关于!的几个用法

!是与命令历史有关的一个特殊字符,该字符常用的应用有一下几个:

  1. !!:连续两个!表示执行上一条命令。
  2. !n:这里的n是数字,表示执行命令历史中的第n条命令。可用命令history查看历史命令列表。
  3. !字符串(字符串大于等于1):执行最近一次以该字符串开头的命令
  4. !$:使用上一次命令的最后一个参数

命令和文件名补全

Tab按键可以补全命令、补全路径或者一个文件名。连续按两次该键会把所有命令或文件名都显示出来。

  • 命令补全
  • 目录补全和文件名补全
  • 命令参数补全 (默认不支持,需要安装一个包:yum install -y bash-comletion,安装后重启系统即可生效)

别名

alias 设置别名

格式 alias 别名字符串='所要替代的指令和该指令的参数'

直接执行 alias 会把目前系统预设的别名全部列出来。

别名的配置文件有:~/.bashrc/etc/profile.d/下的脚本里

每个用户可以在自己的配置文件 ~/.bashrc 中加入自定义的别名。

unalias 取消别名

格式 unalias 别名字符串

通配符

在bash下、可以使用*来匹配零个或多个字符,用?匹配一个字符,[]匹配里面的任一个字符(如 [0-9]),{}表示任取一组。

输入/输出重定向

符号 意义
> 输出重定向
>> 输出追加重定向
< 输入重定向(例子:mail -s "zhuti" somebody@host.com < 邮件内容文件.txt
2> 错误输出重定向
2>> 错误输出追加重定向
2>&1 相当于 > 1.txt 2> 1.txt
2>>&1 相当于 >> 1.txt 2>> 1.txt
&> 把错误和正确的信息重定向到一个文件
&>> 把错误和正确的信息追加重定向到一个文件

管道符

管道符|,它用于将前一个指令的标准输出作为后一个指令的参数。

作业控制

当运行程序时,可以使它暂停(按Ctrl+Z组合键),然后使用fg(foreground的简写)命令恢复它,或是用bg(background的简写)命令使它到后台运行(或是在运行命令的时候在命令后面加一个&符号)。此外,还可以使它终止运行(按Ctrl+C组合键)。

多个被暂停的任务会有编号,使用jobs命令可以查看到放在后台的任务列表以及它们的编号,ID号后面有+ 或 - ,表示优先级。+比-优先级高。在这时使用bg或者fg命令时,则需要在后面加上编号。若不加编号,默认恢复优先级高的。

如何关掉在后台运行的任务呢?这分两种情况:

  1. 如果你没有退出Shell,则应先使用 fg 编号 把任务调到前台,然后按Ctrl+C组合键结束任务。
  2. 关闭了当前Shell,再次打开另一个Shell时,使用jobs命令并不会显示在后台运行或者被暂停的任务。要想关闭这些任务,则需要先知道它们的PID。用这个命令 ps aux | grep 关键字 找到这个进程。若是想结束这个进程,需要使用到kill命令。

kill命令很简单,直接在后面加PID即可 kill PID。如果遇到结束不了的进程时,可以在Kill后面加一个选项,即 kill -9 PID

总结:

命令 意义
Ctrl+Z 暂停任务
fg [编号] 继续任务,把任务调到前台
bg [编号] 把命令调到后台并运行
命令 & 把命令直接丢到后台并运行
jobs 查看进程列表和编号
Ctrl+C 结束当前任务
ps aux 查看相关进程的PID
kill [-9] PID 结束进程

变量

在Linux系统中预设了很多变量,可以供我们使用。我们也可以自定义一些变量,包括局部变量和全局变量。

echo $变量名

echo $变量名 用于查看一个变量的值。

env

env 用于查看系统的全部环境变量。

登陆不同的用户,这些环境变量的值也不同。常见的环境变量如下:

变量名 值的意义
HOSTNAME 主机名
SHELL 当前用户的Shell类型
HISTSIZE 命令历史记录数
MAIL 当前用户的邮件存放目录
PATH 该变量决定了Shell将到哪些目录中寻找命令或程序
PWD 当前目录
LANG 这是与语言相关的环境变量,多语言环境可以修改此环境变量
HOME 当前用户的家目录
LOGNAME 当前用户的登陆名

注意:env命令显示的变量只是环境变量,系统预设的变量其实还有很多,这就需要用到下面的set命令了。

还有两个变需要了解一下:

  • PS1:shell中的提示符
  • PS2:当在shell中执行换行后再继续操作时的提示符

set 和 unset

set 用于查看系统里的全部变量,包括环境变量和用户自定义变量。
unset 变量名 可取消或删除一个变量

export 变量名

export 变量名 声明一个变量为全局变量。

自定义变量

定义变量的方式

  1. 变量=值 只能在当前Shell中使用,不能在子Shell中使用。
  2. export 变量=值 设置了一个全局变量,可以在当前Shell和子Shell中使用。

自定义变量的规则

  1. 设定变量的格式为a=b,其中a为变量名,b为变量的值,等号两边不能有空格。
  2. 变量名只能由字母、数字以及下划线组成,且不能以数字开头。
  3. 当变量内容带有特殊字符时,需要进行特殊处理,如下:
    • 当变量内容带有空格时,需要给该变量加上单引号。如 myname=’Aming Linux’
    • 当变量内容带有单引号,需要给该变量加上双引号。如 myname=”I’m a cocker”
    • 若变量内容中需要用到其它命令,只使用该命令的运行结果作为变量的值,则该命令需要加上反引号。如 myname=`pwd`
    • 变量内容可以累加其它变量的内容,但需要加双引号。如 myname=”$LOGNAME”Aming
      • b=$a”123” 或 b=$a’123’
      • c=$a$b
      • a=$a”增加值”
  4. 注意单引号、双引号和反引号的使用区别:
    • 单引号:里面的内容全部是普通字符
    • 双引号:里面的内容带有本身的意义,比如某个变量
    • 反引号:里面的内容为一个命名,所代表的是该命令执行之后的结果

让自定义变量一直生效

如果想要使自定义的变量一直生效,该如何办到呢?分以下两种情况:

  1. 允许系统内所有用户登陆后都可以使用该变量。
    • 在/etc/profile文件的最后一行加入export 变量=值
    • 运行source /etc/profile. /etc/profile让此配置文件生效
    • 目的达到
  2. 仅允许当前用户使用该变量。
    • 在用户家目录下的.bashrc文件的最后一行加入export 变量=值
    • 运行source .bashrc. .bashrc让配置文件生效
    • 目的达到

变量的配置文件

这些配置文件总结如下表:

配置文件名 文件的作用
/etc/profile 到交互登陆时才执行。这个文件预设了几个重要的变量,例如PATH、USER、LOGNAME、MAIL、INPUTRC、HOSTNAME、HISTSIZE、umask等
/etc/bashrc 用户不用登陆,执行shell就生效。这个文件主要预设umask以及PS1
.bash_profile 该文件定义了用户的个人化路径与环境变量的文件名称。每个用户都可以使用该文件输入专属于自己的shell信息,当用户登陆时,该文件仅仅执行一次
.bashrc 该文件包含专属于自己的shell的bash信息,当登陆或每次打开新的shell时,该文件会被读取。例如,用户可以将自己定义的别名或者自定义变量写到这个文件中
.bash_history 该文件用于记录命令历史
.bash_logout 当退出shell时,会执行该文件。可以将一些清理的工作放到这个文件中

PS1变量的说明

这个PS1就是我们在输入命令时前面的那串字符。如 [root@AmingLinux-105 ~]#,我们来查看一下PS1的值:

1
2
[root@AmingLinux-105 ~]# echo $PS1
[\u@\h \W]\$

其中,\u是用户名,\h是主机名,\W当前目录名,(\w表示的是工作目录的完整绝对路径),\$代表用户身份字符(root为#,普通用户为$)

Shell 中的特殊符号

特殊符号

特殊符号 意义
* 代表零个或多个任意字符
? 只代表一个任意字符
# 注释符,这个符号在Linux中表示注释说明,在后面的内容都会被忽略
\ 脱义字符,将后面的特殊字符还原为普通字符
管道符 将前面命令的输出作为后面命令的输入。支持它的工具有cat、less、head、tail、grep、cut、sort、wc、uniq、tee、tr、split、sed、awk等
$变量名 它可以作为变量前面的标识符
$? 表示上一条的命令执行的返回值,若为0则正确执行,若非零则错误执行
!$ 表示上条命令中的最后一个变量
; 如果在多条命令中间使用这个符号连接,则表示按顺序依次执行
~ 代表用户的家目录,用于cd ~
& 表示把命令放到后台执行,用于命令 &;&&代表逻辑与;&1代表参数1
重定向 >、>>、2>、2>>、<
中括号[] 中括号内为字符组合中的任意一个,可以是一个范围([1-3a-z])

还有两个符号&&和||,将与;放在一起进行总结:

  • command1 ; command2 不管command1是否执行成功,都会执行command2
  • command1 && command2 只有command1执行成功后,才会执行command2
  • command1 || command2 只有command1执行失败了,才会执行command2

几个常用的管道命令

cut

cut 用来截取某一个字段。

格式 cut -d '分隔字符' [-cf] n,这里n是数字。其选项说明如下:

选项 说明
-d 后面跟分隔字符,分隔字符要用单引号括起来
-c 后面接的是第几个字符
-f 后面接的是第几个区块

cut命令的用法说明:

  • -d选项后面加冒号作为分隔字符,-f 1 表示截取第一段,-f和1之间的空格可有可无。示例如下:

    • cut -d ‘分隔符’ -f 1 filename
    • cut -d ‘分隔符’ -f 1,2 filename
    • cut -d ‘分隔符’ -f 1-4 filename
      1
      2
      3
      4
      5
      6
      [root@AmingLinux-105 ~]# cat /etc/passwd | cut -d ':' -f 1 | head -5
      root
      bin
      daemon
      adm
      lp
  • -c选项后面可以一个数字n,也可以是一个区间n1-n2,还可以是多个数字n1,n2,n3。示例如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@AmingLinux-105 ~]# head -n2 /etc/passwd | cut -c2
    o
    i
    [root@AmingLinux-105 ~]# head -n2 /etc/passwd | cut -c1
    r
    b
    [root@AmingLinux-105 ~]# head -n2 /etc/passwd | cut -c1-10
    root:x:0:0
    bin:x:1:1:
    [root@AmingLinux-105 ~]# head -n2 /etc/passwd | cut -c1,3,10
    ro0
    bn:

sort

sort 用作排序

格式 sort [-t 分隔符] [-kn1,n2] [-nru],这里的n1和n2指的是数字,其它选项的含义如下

选项 含义
-t 后面跟分隔字符,作用跟cut的-d选项一样
-n 表示使用纯数字排序
-r 表示反向排序
-u 表示去重复
-kn1,n2 表示由n1区间排序到n2区间,可以只写-kn1,表示只对n1字段排序

sort 命令的用法示例:

  1. sort 如果不加任何选项,则从首字符向后依次按ASCII码值进行比较,最后将它们按升序输出。

    1
    2
    3
    4
    5
    6
    [root@AmingLinux-105 ~]# head -n5 /etc/passwd | sort
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    root:x:0:0:root:/root:/bin/bash
  2. -t 选项后面跟分隔符,-k 选项后面跟单个数字表示对第几个区域的字符串排序,-n选项则表示用纯数字排序。

    1
    2
    3
    4
    5
    6
    [root@AmingLinux-105 ~]# head -n5 /etc/passwd | sort -t: -k3 -n
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
  3. -k 选项后面跟数字n1和n2表示对第n1和n2区域内的字符串排序,-r选项则表示反向排序。

    1
    2
    3
    4
    5
    6
    7
    [root@AmingLinux-105 ~]# head -n5 /etc/passwd | sort -t: -k3,5 -r
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    bin:x:1:1:bin:/bin:/sbin/nologin
    root:x:0:0:root:/root:/bin/bash
    //这里的-k3,5表示对第3区域至第5区域间的字符串排序。

wc

wc 用于统计文档的行数、字符数或词数。

常用选项 含义
不加选项 依次输出文档的行数、词数和字符数
-l 统计行数
-m 统计字符数
-w 统计词数

示例命令如下:

1
2
3
4
5
6
7
8
9
10
[root@AmingLinux-105 ~]# wc /etc/passwd
27 47 1269 /etc/passwd
[root@AmingLinux-105 ~]# wc -l /etc/passwd
27 /etc/passwd
[root@AmingLinux-105 ~]# wc -m /etc/passwd
1269 /etc/passwd
[root@AmingLinux-105 ~]# wc -w /etc/passwd
47 /etc/passwd
一个例子(判断文件有几行,如果行数少于3显示no):
line=`wc -l 4.txt|cut -d ' ' -f1` ; if [ $line -lt "3" ]; then echo "no"; fi

uniq

uniq 用来删除重复的行

该命令只有-c选项最常用,它表示统计重复的行数,并把行数写在最前面。使用uniq前,必须先给文件排序,否则不管用。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@AmingLinux-105 test]# uniq test.txt
11111111111
22222222222
33333333333
55555555555
[root@AmingLinux-105 test]# sort test.txt | uniq
11111111111
22222222222
33333333333
55555555555
[root@AmingLinux-105 test]# sort test.txt | uniq -c
1
1 11111111111
4 22222222222
2 33333333333
1 55555555555

tee

tee 命令类似于重定向>,它的作用是既输出到文件,又输出到屏幕,可以叫它为”双向重定向”。

tee 命令后面跟文件名,且它常用与管道符后面。示例如下:

1
2
3
4
[root@AmingLinux-105 test]# echo "aaaaaaaaaaaaaaaaaaa" | tee test.txt
aaaaaaaaaaaaaaaaaaa
[root@AmingLinux-105 test]# cat test.txt
aaaaaaaaaaaaaaaaaaa

tr

tr 用于替换字符,常用来处理文档中出现的特殊符号,如DOS文档中出现的^M。这个工具是针对一个字符来讲的,有一定的局限性。

常用选项 含义
-d 表示删除某个字符,后面跟要删除的字符
-s 表示删除重复的字符

示例如下:

  1. tr 常用于把小写字母变成大写字母,如tr '[a-z]' '[A-Z]'

    1
    2
    3
    [root@AmingLinux-105 test]# head -n2 /etc/passwd | tr '[a-z]' '[A-Z]'
    ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
    BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN
  2. tr 还可以替换一个字符。

    1
    2
    3
    [root@AmingLinux-105 test]# grep 'root' /etc/passwd | tr 'r' 'R'
    Root:x:0:0:Root:/Root:/bin/bash
    opeRatoR:x:11:0:opeRatoR:/Root:/sbin/nologin

split

split 用于切割文档,常用选项为-b和-l

常用选项 含义
-b 依据大小来分割文档,单位为byte
-l 依据行数来分割文档

示例如下:

1
2
3
4
[root@AmingLinux-105 test]# cp /etc/passwd .
[root@AmingLinux-105 test]# split -b 500 passwd
[root@AmingLinux-105 test]# ls
1 2 3 4 passwd test.txt test.txt.zip xaa xab xac

如果split不指定目标文件名,则会以xaa、xab、xac….这样的文件名来存储切割后的文件。当然,也可以指定目标文件名。示例如下:

1
2
3
4
5
[root@AmingLinux-105 test]# rm -f xa*
[root@AmingLinux-105 test]# split -b 500 passwd new
[root@AmingLinux-105 test]# ls
1 2 3 4 newaa newab newac passwd test.txt test.txt.zip
[root@AmingLinux-105 test]# split -b 1M passwd new

使用-l选项的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@AmingLinux-105 test]# rm -f new*
[root@AmingLinux-105 test]# split -l 10 passwd
[root@AmingLinux-105 test]# ls
1 2 3 4 passwd test.txt test.txt.zip xaa xab xac
[root@AmingLinux-105 test]# wc -l *
0 1
0 2
0 3
wc: 4: 是一个目录
0 4
27 passwd
1 test.txt
0 test.txt.zip
10 xaa
10 xab
7 xac
55 总用量

OK

0%